Constants
This document provides guidelines for using constants in the Meall an Óige application.
When to Use Constants
Constants should be used in the following scenarios:
- Magic Numbers/Strings: Any numeric or string value that has meaning in the application and appears more than once
- Configuration Values: Durations, delays, volumes, speeds, etc. that might need adjustment
- Enumerations: Sets of related values that represent states, types, or options
- API Endpoints: URLs, paths, and resource identifiers
- Application-wide Settings: Names, titles, and configuration that applies across components
Constant Organization
Component-Level Constants
Component-level constants should be defined at the top of the file, immediately after imports:
// Audio-related constants
const HITBOX_SOUND_VOLUME = 0.5;
const HITBOX_SOUND_SPEED = 1;
// Timing constants
const DELAY_AFTER_CORRECT_DING = 200;
const DELAY_AFTER_ERROR_DIDU = 200;
const DELAY_BEFORE_TUTORIAL_PLAYBACK = 200;
Use component-level constants when:
- The constant is only relevant to that specific component
- The value is unlikely to be reused elsewhere
- The constant helps document intent within the component
Application-Level Constants
Application-wide constants should be stored in dedicated files in the src/constants directory:
// In src/constants/TRANSITION_SCREEN.js
export const TRANSITION_SCREEN_STATE = {
INVISIBLE: "INVISIBLE",
TRANSITION_IN: 'TRANSITION_IN',
LOADING: 'LOADING',
TRANSITION_OUT: 'TRANSITION_OUT'
};
export const TRANSITION_SCREEN_TIMING = {
TRANSITION_IN_DURATION: 300,
TRANSITION_OUT_DURATION: 200,
DELAY_AFTER_LOADING: 100,
// ...
};
Use application-level constants when:
- The constant is used across multiple components
- The value represents a fundamental configuration setting
- Changes to the constant would affect multiple parts of the application
Naming Conventions
Case Style
-
UPPER_SNAKE_CASE: Use for individual constants and constant objects
const HITBOX_SOUND_VOLUME = 0.5;
const GAME_STATES = { ... }; -
File Names: Constant files should use UPPERCASE with underscores
TRANSITION_SCREEN.js
LANGUAGES.js
MEALL_AN_OIGE.js
Grouping Related Constants
Group related constants into objects when they form a logical unit:
const GAME_STATES = {
TUTORIAL: "TUTORIAL",
PROMPTING: "PROMPTING",
ANSWERING: "ANSWERING",
CORRECT_ANSWER: "CORRECT_ANSWER",
WRONG_ANSWER: "WRONG_ANSWER",
VICTORY: "VICTORY",
DEFEAT: "DEFEAT",
};
Namespace Constants
Namespace constants by their domain to prevent collisions:
// Not recommended
export const DURATION = 300;
// Recommended
export const TRANSITION_SCREEN_TIMING = {
TRANSITION_IN_DURATION: 300,
// ...
};
Importing and Using Constants
Import constants explicitly:
// Prefer this
import { TRANSITION_SCREEN_TIMING, TRANSITION_SCREEN_STATE } from "constants/TRANSITION_SCREEN";
// Avoid this (unless importing many constants)
import * as TransitionConstants from "constants/TRANSITION_SCREEN";
Use constants directly in code:
setTimeout(() => {
playSound(tutorialSoundPlayer, { volume: HITBOX_SOUND_VOLUME });
}, DELAY_BEFORE_TUTORIAL_PLAYBACK);
// State management
if (gameState === GAME_STATES.TUTORIAL) {
// Do something
}
Best Practices
- Documentation: Include comments above constant groups explaining their purpose
- Units: Include units in constant names when applicable (e.g.,
DELAY_MS_BEFORE_ANIMATION) - Default Values: Use constants for default values even if they only appear once
- Platform-specific Constants: Group platform-specific constants together
- Avoid Duplication: Don't repeat the same constant values across files
- Semantic Names: Name constants based on their purpose, not their value
Example Structure
Here's an example of how constants should be organized:
src/
constants/
LANGUAGES.js // Language-related constants
TRANSITION_SCREEN.js // Screen transition constants
COLORS.js // Color palette constants
TIMING.js // Application-wide timing constants
API_ENDPOINTS.js // API endpoints and URLs
STORAGE_KEYS.js // Storage key constants
APP.js // General application constants
Anti-patterns to Avoid
- Mixing variable cases within a single constant object
- Using non-descriptive constant names (
const X = 100;) - Hardcoding values that should be constants
- Creating separate constant files for values used in only one component
- Not using exported constants from the
constantsdirectory when they exist